package com.tarena.lbs.service.impl;

import com.tarena.lbs.entity.*;
import com.tarena.lbs.enums.CouponCodeStatusEnum;
import com.tarena.lbs.enums.UserCouponStatusEnum;
import com.tarena.lbs.mapper.CouponMapper;
import com.tarena.lbs.mapper.UserCouponsMapper;
import com.tarena.lbs.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class UserCouponsServiceImpl implements UserCouponsService {

    private static final Logger log = LoggerFactory.getLogger(UserCouponsServiceImpl.class);

    @Autowired
    private UserCouponsMapper userCouponsMapper;

    @Autowired
    private CouponService couponService;

    @Autowired
    private CouponCodeService couponCodeService;

    @Autowired
    private CouponStockService couponStockService;

    @Autowired
    private CouponActivityService couponActivityService;

    // 新增：注入 CouponMapper
    @Autowired
    private CouponMapper couponMapper;

    @Override
    @Transactional
    public boolean insertUserCoupon(UserCoupons userCoupon) {
        int result = userCouponsMapper.insertUserCoupon(userCoupon);
        return result > 0;
    }

    @Override
    public List<UserCoupons> listUserCouponsByUserId(Integer userId) {
        return userCouponsMapper.listUserCouponsByUserId(userId);
    }

    @Override
    @Transactional
    public boolean updateUserCouponStatus(Integer id, Integer status) {
        int result = userCouponsMapper.updateUserCouponStatus(id, status);
        return result > 0;
    }

    @Override
    public UserCoupons getUserCouponByCode(String couponCode) {
        return userCouponsMapper.getUserCouponByCode(couponCode);
    }

    @Override
    public int countUserCouponsByUserIdAndCouponId(Integer userId, Integer couponId) {
        return userCouponsMapper.countUserCouponsByUserIdAndCouponId(userId, couponId);
    }

    @Override
    @Transactional
    public boolean receiveCoupon(Integer userId, Integer couponId, Integer activityId) {
        // 参数校验
        if (userId == null || couponId == null) {
            return false;
        }

        // 检查活动是否有效
        if (activityId != null && !couponActivityService.isActivityValid(activityId)) {
            return false;
        }

        // 获取优惠券信息
        Coupon coupon = couponService.getCouponById(couponId);
        if (coupon == null) {
            return false;
        }

        // 检查优惠券状态
        if (coupon.getStatus() != 1) {
            return false;
        }

        // 检查优惠券是否过期
        Date now = new Date();
        if (now.before(coupon.getStartDate()) || now.after(coupon.getEndDate())) {
            return false;
        }

        // 检查用户是否已领取过该优惠券
        int count = countUserCouponsByUserIdAndCouponId(userId, couponId);
        if (count >= coupon.getMaxUsageLimit()) {
            return false;
        }

        // 检查库存是否充足
        if (!couponStockService.decreaseStock(couponId, 1)) {
            return false;
        }

        // 获取可用的优惠券码
        List<CouponCode> availableCodes = couponCodeService.listAvailableCodesByCouponId(couponId, 1);
        if (availableCodes == null || availableCodes.isEmpty()) {
            // 如果没有可用的优惠券码，创建新的
            CouponCode newCode = new CouponCode();
            newCode.setCouponId(couponId);
            newCode.setBusinessId(coupon.getBusinessId());
            newCode.setStatus(CouponCodeStatusEnum.UNASSIGNED.getCode());
            newCode.setCouponCode(couponCodeService.generateCouponCode());
            newCode.setCreateAt(new Date());
            newCode.setUpdateAt(new Date());
            couponCodeService.batchInsertCouponCodes(Arrays.asList(newCode));
            availableCodes = Arrays.asList(newCode);
        }

        // 分配优惠券码
        CouponCode code = availableCodes.get(0);
        if (!couponCodeService.updateCouponCodeStatus(code.getId(), CouponCodeStatusEnum.ASSIGNED.getCode())) {
            return false;
        }

        // 创建用户优惠券记录
        UserCoupons userCoupon = new UserCoupons();
        userCoupon.setUserId(userId);
        userCoupon.setCouponId(couponId);
        userCoupon.setReceiveChannel(1); // 1: 活动领取
        userCoupon.setStatus(UserCouponStatusEnum.UNUSED.getCode());
        userCoupon.setCreateAt(new Date());
        userCoupon.setUpdateAt(new Date());
        userCoupon.setActivityId(activityId);
        userCoupon.setCouponCode(code.getCouponCode());
        userCoupon.setShopId(coupon.getBusinessId());
        userCoupon.setCouponType(coupon.getCouponType());
        userCoupon.setCouponValue(coupon.getDiscountValue());

        // 插入用户优惠券记录
        return insertUserCoupon(userCoupon);
    }

    @Override
    @Transactional
    public boolean useCoupon(String couponCode, String orderNo) {
        // 参数校验
        if (couponCode == null || orderNo == null) {
            return false;
        }

        // 获取用户优惠券
        UserCoupons userCoupon = getUserCouponByCode(couponCode);
        if (userCoupon == null) {
            return false;
        }

        // 检查优惠券状态
        if (!userCoupon.getStatus().equals(UserCouponStatusEnum.UNUSED.getCode())) {
            return false;
        }

        // 获取优惠券信息
        Coupon coupon = couponService.getCouponById(userCoupon.getCouponId());
        if (coupon == null) {
            return false;
        }

        // 检查优惠券是否过期
        Date now = new Date();
        if (now.after(coupon.getEndDate())) {
            return false;
        }

        // 更新优惠券状态为已使用
        userCoupon.setStatus(UserCouponStatusEnum.USED.getCode());
        userCoupon.setOrderNo(orderNo);
        userCoupon.setUsedTime(now);
        userCoupon.setUpdateAt(now);

        // 更新数据库
        return updateUserCouponStatus(userCoupon.getId(), UserCouponStatusEnum.USED.getCode());
    }

    @Override
    @Transactional
    public boolean deleteUserCoupon(Integer id, Integer userId) {
        // 参数校验
        if (id == null || userId == null) {
            log.error("删除用户优惠券失败：参数为空");
            return false;
        }

        // 检查优惠券是否存在
        UserCoupons userCoupon = userCouponsMapper.getUserCouponByCode(String.valueOf(id));
        if (userCoupon == null || !userCoupon.getUserId().equals(userId)) {
            log.error("删除用户优惠券失败：优惠券不存在或不属于当前用户，id={}, userId={}", id, userId);
            return false;
        }

        // 执行删除
        int result = userCouponsMapper.deleteUserCoupon(id, userId);
        if (result > 0) {
            log.info("删除用户优惠券成功，id={}, userId={}", id, userId);
            return true;
        } else {
            log.error("删除用户优惠券失败，id={}, userId={}", id, userId);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean batchDeleteUserCoupons(List<Integer> ids, Integer userId) {
        // 参数校验
        if (ids == null || ids.isEmpty() || userId == null) {
            log.error("批量删除用户优惠券失败：参数为空");
            return false;
        }

        // 执行批量删除
        int result = userCouponsMapper.batchDeleteUserCoupons(ids, userId);
        if (result > 0) {
            log.info("批量删除用户优惠券成功，ids={}, userId={}, 删除数量={}", ids, userId, result);
            return true;
        } else {
            log.error("批量删除用户优惠券失败，ids={}, userId={}", ids, userId);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean physicallyDeleteUserCoupon(Integer id, Integer userId) {
        // 参数校验
        if (id == null || userId == null) {
            log.error("物理删除用户优惠券失败：参数为空");
            return false;
        }

        // 检查优惠券是否存在
        UserCoupons userCoupon = userCouponsMapper.getUserCouponByCode(String.valueOf(id));
        if (userCoupon == null || !userCoupon.getUserId().equals(userId)) {
            log.error("物理删除用户优惠券失败：优惠券不存在或不属于当前用户，id={}, userId={}", id, userId);
            return false;
        }

        // 执行物理删除（谨慎使用）
        int result = userCouponsMapper.physicallyDeleteUserCoupon(id, userId);
        if (result > 0) {
            log.info("物理删除用户优惠券成功，id={}, userId={}", id, userId);
            return true;
        } else {
            log.error("物理删除用户优惠券失败，id={}, userId={}", id, userId);
            return false;
        }
    }


}